home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / CRS / crs53.d81 / 28may87s.pma / CXIO.ASM < prev    next >
Assembly Source File  |  1979-12-31  |  25KB  |  1,393 lines

  1.  
  2.  
  3.  
  4.  
  5. ;
  6.     title    'C128 BIOS, main I/O and sys functions     28 Apr 86'
  7.  
  8. ;
  9. ;    This module contains CXIO,CXINIT,CXMOVE and CXTIME.
  10. ;
  11.     maclib    cpm3
  12.  
  13.     maclib    z80
  14.  
  15.     maclib    cxequ
  16.  
  17.     maclib    modebaud
  18.  
  19.  
  20.     public    ?init,?ldccp,?rlccp
  21.  
  22.     public    ?user,?di$int
  23.  
  24.     extrn    ?sysint
  25.  
  26. bdos    equ    5    
  27.  
  28.     extrn    @civec,@covec,@aivec,@aovec,@lovec
  29.     extrn     ?bnksl
  30.  
  31.     public    ?cinit,?ci,?co,?cist,?cost
  32.     public    @ctbl
  33.     extrn    ?kyscn
  34.  
  35. ; Utility routines in standard BIOS
  36.     extrn    ?wboot        ; warm boot vector
  37.     extrn    ?pmsg        ; print message @<HL> up to 00
  38.                 ; saves <BC> & <DE>
  39.     extrn    ?pdec        ; print binary number in <A> from 0 to 99.
  40.     extrn    ?pderr        ; print BIOS disk error header
  41.     extrn    ?conin,?cono    ; con in and out
  42.     extrn    ?const        ; get console status
  43.  
  44.     extrn    @hour,@min,@sec,@date,?bnksl
  45.     public    ?time
  46.  
  47.     page
  48. ;
  49. ;    keyboard scanning routine 
  50. ;
  51.     extrn    ?get$key,?int$cia
  52.     extrn    Fx$V$tbl
  53. ;
  54. ;    links to 80 column display
  55. ;
  56.     extrn    ?out80,?int80
  57.     extrn    ?out40,?int40
  58.  
  59.     extrn    ?pt$i$1101,?pt$o$1,?pt$o$2
  60.     extrn    ?convt
  61. ;    extrn    ?pt$s$1101
  62.  
  63. ;
  64. ;    bios8502 function routines
  65. ;
  66.     public    ?fun65
  67.  
  68. ;
  69. ;
  70. ;
  71.     public    ?intbd
  72.     extrn    ?int65,?in65,?ins65,?out65,?outs65
  73.  
  74. ;    cseg
  75. ;trace:
  76. ;    xthl            ; save hl on stack
  77. ;    push    psw
  78. ;    call    ?pmsg        ; DE and BC saved by ?pmsg
  79. ;    pop    psw
  80. ;    xthl
  81. ;    ret
  82. ;
  83. ;    CSEG
  84. ;disp$A:
  85. ;    push    psw        ;;;test
  86. ;    ani    0fh        ;;;test
  87. ;    adi    90h        ;;;test
  88. ;    daa            ;;;test
  89. ;    aci    40h        ;;;test
  90. ;    daa            ;;;test
  91. ;    sta    low$test    ;;;test
  92. ;    pop    psw        ;;;test
  93. ;    rar            ;;;test
  94. ;    rar            ;;;test
  95. ;    rar            ;;;test
  96. ;    rar            ;;;test
  97. ;    ani    0fh        ;;;test
  98. ;    adi    90h        ;;;test
  99. ;    daa            ;;;test
  100. ;    aci    40h        ;;;test
  101. ;    daa            ;;;test
  102. ;    sta    hi$test        ;;;test
  103. ;    call    trace        ;;;test
  104. ;hi$test:            ;;;test
  105. ;    db    31        ;;;test
  106. ;low$test:            ;;;test
  107. ;    db    31        ;;;test
  108. ;    db    ' '        ;;;test
  109. ;    db    0        ;;;test
  110. ;    ret            ;;;test
  111. ;
  112.     page
  113.  
  114.     DSEG
  115. ?fun65:
  116.     sta    vic$cmd            ; save the command passed in A
  117.    if    not use$6551
  118. fun$di$wait:
  119.     lda    RS232$status
  120.     ani    11000010b        ; char to Xmit, Xmiting or receiving ?
  121.     jrnz    fun$di$wait        ; yes, wait for int to clean up
  122.    endif
  123.     di
  124.     lda    force$map        ; get current MMU configuration
  125.     push    psw            ; save it
  126.     sta    io$0            ; make I/O 0 current
  127.  
  128.     lxi    d,1            ; D=0,  E=1
  129.    if    use$fast
  130.     lxi    b,VIC$speed
  131.     inp    a
  132.     sta    sys$speed
  133.     outp    d            ; set slow mode (1 2 MHz Z80)
  134.    endif
  135.     lxi    b,page$1$h
  136.     outp    d
  137.     dcr    c
  138.     outp    e            ; page 1, 0-1
  139.     dcr    c
  140.     outp    d
  141.     dcr    c
  142.     outp    d            ; page 0, 0-0
  143.     call    enable$6502+6        ; go run the 8502
  144.     mvi    c,low(page$1$h)
  145.     outp    e
  146.     dcr    c
  147.     outp    e            ; page 1, 1-1
  148.     dcr    c
  149.     outp    e
  150.     dcr    c
  151.     outp    d            ; page 0, 1-0
  152.    if    use$fast
  153.     lxi    b,VIC$speed
  154.     lda    sys$speed        ; get desired system speed
  155.     outp    a            ; set speed (2 or 4 MHz Z80)
  156.    endif
  157.     pop    psw            ; recover the MMU config.
  158.     sta    force$map        ; restore it
  159.     ei                ; turn interrupts back on
  160.     lda    vic$data        ; get command results
  161.     ora    a            ; set the zero flag if A=0
  162.     ret
  163.  
  164. ?di$int:
  165.    if    not use$6551
  166.     push    psw
  167. di$int$1:
  168.     lda    RS232$status        ; character to Xmit or currently
  169.     ani    11000010b        ; ..transmitting or receiving ?
  170.     jrnz    di$int$1        ; yes, wait for int to clean up
  171.     pop    psw
  172.    endif
  173.     di
  174.     ret
  175.  
  176.     page
  177. ;
  178. ;    set up the MMU for CP/M Plus
  179. ;
  180.     DSEG            ; init done from banked memory
  181. ?init:
  182.     mvi    a,3eh            ; force MMU into I/O space
  183.     sta    force$map        ;
  184.     lxi    h,mmu$table+11-1    ; table of 11 values
  185.     lxi    b,mmu$start+11-1    ; to to MMU registers
  186.     mvi    d,11            ; move all 11 bytes to the MMU
  187.  
  188. init$mmu$loop:
  189.     mov    a,m
  190.     outp    a
  191.     dcx    h
  192.     dcx    b
  193.     dcr    d
  194.     jrnz    init$mmu$loop
  195.  
  196.     mvi    a,1            ; enable track and sector status
  197.     sta    stat$enable        ; on the status line
  198. ;    mvi    a,1            ; no parity, 8 bits, 1 stop bit
  199.     sta    XxD$config
  200. ;
  201.    if    use$6551
  202.     lxi    h,int$6551
  203.    else
  204.     lxi    h,usart
  205.    endif
  206.     shld    usart$adr
  207.  
  208.     lxi    h,?convt
  209.     shld    prt$conv$1
  210.     shld    prt$conv$2
  211.  
  212.     lxi    h,Fx$V$tbl
  213.     shld    key$FX$function
  214. ;
  215. ; install I/O assignments
  216. ;
  217.     lxi    h,4000h+2000h         ; 80 and 40 column drivers
  218.     shld    @covec
  219.     mvi    h,80h
  220.     shld    @civec            ; assign console input to keys
  221.     mvi    h,10h
  222.     shld    @lovec            ; assign printer to LPT:
  223.     mvi    h,00h
  224.     shld    @aivec
  225.     shld    @aovec            ; assign rdr/pun port
  226.  
  227.     page
  228. ;
  229. ; print sign on message
  230. ;
  231.     call    prt$msg            ; print signon message
  232.     db    'Z'-'@'            ; initialize screen pointers
  233.     db    esc,esc,esc
  234.     db    purple+50h        ; set character color
  235.     db    esc,esc,esc
  236.     db    black+60h        ; set background (BG) color
  237.     db    esc,esc,esc
  238.     db    brown+70h        ; set border color
  239.     db    'Z'-'@'            ; home and clear screen (to BG color)
  240.  
  241.     db    lf,lf,lf
  242.     if    use$fast
  243.     db    'Fast '
  244.     endif
  245.  
  246.     if    use$6551
  247.     db    '/w 6551 '
  248.     endif
  249.  
  250.     db    'CP/M 3.0'
  251.     if    not banked
  252.     db    ' Non-Banked'
  253.     endif
  254.     db    ' On the Commodore 128 '
  255.     date
  256.     warning
  257.     db    cr,lf
  258.     db    '          ',0
  259.  
  260. ;
  261. ;    set CONOUT driver to correct screen
  262. ;
  263.     lxi    h,4000h            ; 80 column screen vector    
  264.     call    read$d505
  265.     ral
  266.     jrnc    set$screen
  267.     mvi    a,'4'
  268.     sta    screen$num
  269.     mvi    h,20h            ; 40 column screen vector
  270.  
  271. set$screen:
  272.     call    prt$msg            ; HL saved
  273. screen$num:
  274.     db    '80 column display',cr,lf,lf,lf,lf,0
  275.     shld    @covec            ; assign console output to CRT: (40/80)
  276.  
  277.     page
  278.  
  279. ;
  280. ;
  281.     mvi    a,-1            ; set block move to NORMAL mode
  282.     sta    source$bnk
  283. ;
  284. ;    install mode 2 page vectors
  285. ;
  286.     mvi    a,JMP
  287.     sta    INT$vector        ; install a JMP at vector location
  288.     lxi    h,?sysint
  289.     shld    INT$vector+1        ; install int$handler adr
  290. ;
  291. ; A software fix is  required for the lack of hardware to force the
  292. ; LSB of the INT vector to 0. If the bus floats INT VECT could be
  293. ; read as 0FFh; thus ADRh=I (I=0FCh) ADRl=FF for first read, and
  294. ; ADRh=I+1 ADRl=00 for second, to ensure that control is retained
  295. ; 0FD00h will also have FDh in it.
  296. ;
  297.     lxi    h,int$block        ; FC00h
  298.     lxi    d,int$block+1        ; FC01h
  299.     lxi    b,256-1+1        ; interrupt pointer block
  300.     mvi    m,INT$vector/256    ; high and low are equal (FD)
  301.     ldir
  302.     mvi    a,INT$block/256
  303.     stai                ; set interrupt page pointer
  304.     im2                ; enable mode 2 interrupts
  305.  
  306.     page
  307. ;
  308. ;
  309.     mvi    a,vicinit        ; null command just to setup BIOS8502
  310.     call    ?fun65
  311. ;
  312. ;
  313. ;
  314.     lda    sys$freq        ; 0=60Hz 0FFh=50Hz
  315.     ani    80h            ; 0=60Hz 080h=50Hz
  316.     mov    l,a            ; save in L
  317.     lxi    b,cia$1+0eh        ; point to CRA
  318.     inp    a            ; get old config
  319.     ani    7fh            ; clear freq bit
  320.     ora    l            ; add in new freq bit
  321.     outp    a            ; set new config
  322.  
  323.     mvi    c,8            ; start RTC
  324.     outp    a
  325.  
  326.     lxi    h,date$hex
  327.     shld    @date            ; set date to system data
  328.  
  329. ;
  330. ;    setup the sound variables
  331. ;
  332.     lhld    key$tbl
  333.     lxi    d,58*4
  334.     dad    d
  335.     mov    e,m
  336.     inx    h
  337.     mov    d,m
  338.     inx    h
  339.     xchg
  340.     shld    sound1            ; H=SID reg 24, L=SID reg 5
  341.     xchg
  342.     mov    e,m
  343.     inx    h
  344.     mov    d,m
  345.     xchg
  346.     shld    sound2            ; H=SID reg 6, L=SID reg 1
  347.     lxi    h,9
  348.     dad    d
  349.     mov    e,m
  350.     inx    h
  351.     mov    d,m
  352.     xchg
  353.     shld    sound3            ; H=SID reg 4 then L=SID reg 4 
  354. ;
  355. ;    set-up key click sound registers
  356. ;
  357.     lxi    b,sid+7
  358.     lxi    h,0040h
  359.     outp    l            ; (sid+7)=40h
  360.     inr    c
  361.     outp    l            ; (sid+8)=40h
  362.     mvi    c,low(sid+12)
  363.     outp    h            ; (sid+12)=0  Attack=2ms, Decay=6ms
  364.     inr    c
  365.     outp    h            ; (sid+13)=0  Sustain=0,  Release=6ms
  366.     mvi    a,6
  367.     sta    tick$vol        ; set keyclick volumn level
  368. ;
  369. ;    set up interrupts for key scan (not software usart)
  370. ;
  371.    if    use$6551
  372.     lxi    d,2273            ; int at 150 BAUD rate
  373.     lxi    b,CIA1+timer$b$low    ;
  374.     outp    e            ;
  375.     inr    c            ; point to timer$b$high
  376.     outp    d            ;
  377.  
  378.     mvi    a,11h            ;
  379.     mvi    c,CIA$ctrl$b        ; turn on timer B
  380.     outp    a            ;
  381.  
  382.     lxi    b,CIA2+data$b        ; setup user port for RS232
  383.     inp    a            ; get old data
  384.     ori    6            ; set CTS and DTR
  385.     outp    a            ; update it
  386.    endif
  387.      ret
  388.  
  389.  
  390. mmu$table:
  391.     mmu$tbl$M
  392.  
  393.     page
  394. ;
  395. ;
  396. ;
  397.     CSEG
  398. prt$msg:
  399.     xthl
  400.     call    ?pmsg
  401.     xthl
  402.     ret
  403.  
  404.  
  405. ;
  406. ;    placed in common memory to keep IO from stepping on this code
  407. ;        always called from bank 0
  408. ;
  409.     CSEG
  410. read$d505:
  411.     sta    io$0            ; enable MMU (not RAM)
  412.     lxi    b,0d505h
  413.     inp    a            ; read 40/80 column screen
  414.     sta    bank$0            ; re-enable RAM
  415.     ret
  416.  
  417.     page
  418. ;
  419. ;
  420. ;
  421.     DSEG
  422.    if    not use$6551
  423. init$RS232:
  424.     di
  425.  
  426.     xra    a
  427.     sta    RS232$status
  428.     lxi    h,RxD$buf$count        ; clear the count
  429.     mvi    m,0
  430.     inr    l            ; point to RxD$buf$put
  431.     mvi    m,low(RxD$buffer)
  432.     inr    l            ; point to RxD$buf$get
  433.     mvi    m,low(RxD$buffer)
  434.  
  435.     lxi    h,NTSC$baud$table
  436.     lda    sys$freq
  437.     ora    a
  438.     jrz    use$NTSC
  439.     lxi    h,PAL$baud$table
  440. use$NTSC:
  441.     lda    RS232$baud
  442.     cpi    baud$1200        ; baud rate less then 1200 baud
  443.     jrc    baud$ok            ; yes, go set it
  444.     mvi    a,baud$1200        ; no, 1200 baud is the max
  445.     sta    RS232$baud        ; (change to 1200 baud)
  446.  
  447. baud$ok:
  448.     mov    e,a
  449.     mvi    d,0
  450.     dad    d            ; +1X
  451.     dad    d            ; +1X
  452.     dad    d            ; +1X = +3X
  453.     mov    e,m
  454.     inx    h
  455.     mov    d,m
  456.     inx    h            ;
  457.     mov    a,m            ; get rate #
  458.     sta    int$rate        ;
  459.     lxi    b,CIA1+timer$b$low    ;
  460.     outp    e            ;
  461.     inr    c            ; point to timer$b$high
  462.     outp    d            ;
  463.  
  464.     mvi    a,11h            ;
  465.     mvi    c,CIA$ctrl$b        ; turn on timer B
  466.     outp    a            ;
  467.  
  468.     lxi    b,CIA2+data$b        ; setup user port for RS232
  469.     inp    a            ; get old data
  470.     ori    6            ; set CTS and DTR
  471.     outp    a            ; update it
  472.     ei
  473.     ret
  474.  
  475.     page
  476. ;
  477. ;    NTSC rates (1.02273 MHz)
  478. ;
  479. NTSC$baud$table:
  480.     dw    6818            ; no baud rate     (6666.47)
  481.     db    1
  482.     dw    6818            ; 50    6666.7us (6666.47)
  483.     db    1
  484.     dw    4545            ; 75    4444.4us (4443.99)
  485.     db    1
  486.     dw    3099            ; 110    3030.3us (3030.13)
  487.     db    1
  488.     dw    2544            ; 134    2487.6us (2487.46)
  489.     db    1
  490.     dw    2273            ; 150    2222.2us (2222.48)
  491.     db    2
  492.     dw    1136            ; 300    1111.1us (1110.75)
  493.     db    3
  494.     dw    568            ; 600     555.6us ( 555.38)
  495.     db    6
  496.     dw    284            ; 1200     277.8us ( 277.69)
  497.     db    12
  498.  
  499. ;
  500. ;    PAL rates (0.98525 MHz)
  501. ;
  502. PAL$baud$table:
  503.     dw    6568            ; no baud rate      (6666.32)
  504.     db    1
  505.     dw    6568            ; 50     6666.7us (6666.32)
  506.     db    1
  507.     dw    4379            ; 75     4444.4us (4444.56)
  508.     db    1
  509.     dw    2986            ; 110     3030.3us (3030.70)
  510.     db    1
  511.     dw    2451            ; 134     2487.6us (2487.69)
  512.     db    1
  513.     dw    2189            ; 150     2222.2us (2221.77)
  514.     db    2
  515.     dw    1095            ; 300     1111.1us (1111.39)  300*3
  516.     db    3
  517.     dw    547            ; 600      555.6us ( 555.19)  600*3
  518.     db    6
  519.     dw    274            ; 1200    277.8us ( 278.10) 1200*3
  520.     db    12
  521.  
  522.     page
  523. ;
  524. ;
  525. ;
  526. out$RS232:
  527.     call    out$st$RS232
  528.     jrz    out$RS232
  529.     mov    a,c
  530.     sta    xmit$data        ; get character to send in A
  531.     lxi    h,RS232$status
  532.     setb    7,m            ; set Xmit request bit
  533.     ret
  534.  
  535. ;
  536. ;
  537. ;
  538. out$st$RS232:
  539.     lda    RS232$status
  540.     ani    80h            ; bit 8 set if busy
  541.     xri    80h            ; A cleared if busy (=80h if not)
  542.     rz
  543.     ori    0ffh            ; A=ff if ready (not busy)
  544.     ret
  545.  
  546. ;
  547. ;
  548. ;
  549. in$RS232:
  550.     call    in$st$RS232
  551.     jrz    in$RS232
  552.     lda    recv$data
  553.     lxi    h,RS232$status
  554.     res    0,m
  555.     ret
  556.  
  557. ;
  558. ;
  559. ;
  560. in$st$RS232:
  561.     lda    RS232$status
  562.     ani    1
  563.     rz
  564.     ori    0ffh            ; set data ready (-1)
  565.     ret
  566.    endif
  567.     page
  568. ;
  569. ;    this routine is used to provide the user with a method
  570. ;    of interfacing with low level system functions
  571. ;
  572.     CSEG
  573. ;
  574. ;    input:
  575. ;        all registers except HL and A are passed to function
  576. ;
  577. ;    output:
  578. ;        all resisters from function are preserved
  579. ;
  580. ?user:
  581.     shld    user$hl$temp
  582.     xchg
  583.     shld    de$temp            ; save DE for called function
  584.  
  585.     mov    e,a            ; place function number in E
  586.     mvi    a,num$user$fun-1    ; last legal function number
  587.  
  588.     call    vector            ; function
  589. usr$tb:    dw    read$mem$0        ; 0
  590.     dw    write$mem$0        ; 1
  591.     dw    ?kyscn            ; 2
  592.     dw    do$rom$fun        ; 3  (L=function #)     
  593.     dw    do$6502$fun        ; 4  (L=function #)
  594.     dw    read$d505        ; 5  returns MMU reg in A
  595.     dw    code$error        ; not 0 to 5 ret version number in HL
  596.  
  597. num$user$fun    equ    ($-usr$tb)/2
  598.  
  599.     page
  600. ;
  601. ;    address in DE is read and returned in C
  602. ;    A=0 if no error
  603. ;
  604.     DSEG
  605. read$mem$0:
  606.     ldax    d            ; read location addressed by DE
  607.     mov    c,a            ; value returned in C
  608.     xra    a            ; clear error flag
  609.     ret
  610.  
  611. ;
  612. ;    address in DE is written to with value in C
  613. ;    A=0 if no errors
  614. ;
  615. write$mem$0:
  616.     mvi    a,-1            ; get error flag and 0ffh value
  617.     cmp    d            ; do not allow write from FF00 to FFFF
  618.                     ;   this is 8502 space, MMU direct reg.
  619.     rz
  620.     mov    a,d
  621.     cpi    10h            ; do not allow write from 0000 to 0FFF
  622.                     ;   this is ROM space
  623.     mvi    a,-1            ; get error flag
  624.     rc                ; return if 00h to 0fh
  625.     mov    a,c
  626.     stax    d
  627.     xra    a            ; clear error flag 
  628.     ret
  629.  
  630.     page
  631. ;
  632. ;    This is the function code entry point for direct execution
  633. ;    of driver functions. If the MSB of the function number is
  634. ;    set, the 40 column driver is used; else the 80 column drive 
  635. ;    is used.
  636. ;
  637. do$rom$fun:
  638.     lhld    user$hl$temp        ; get HL (L=fun #)
  639.  
  640.     mvi    a,7eh            ; only allow even functions
  641.     ana    l
  642.     cpi    79h
  643.     jrc    no$hl$req
  644.     lhld    @dma            ; HL will be passed in @dma by
  645.     push    h            ; ..the user
  646. no$hl$req:
  647.     mov    l,a
  648.     rst    5            ; call rom functon (RCALL) L=fun #    
  649.     ret
  650.  
  651. ;    mvi    a,7eh            ; only allow even functions
  652. ;    ana    l
  653. ;    sta    no$hl$req+1
  654. ;    cpi    79h
  655. ;    jrc    no$hl$req
  656. ;    lhld    @dma            ; HL will be passed in @dma by
  657. ;    push    h            ; ..the user
  658. ;no$hl$req:
  659. ;    will be changed to RCALL xx   RET for next release (ROM FN 7A, 7C
  660. ;        and 7E will not function with current code, they expect
  661. ;        a return address on the stack
  662. ;
  663. ;    RJMP    5Eh            ; unused function, real fun# installed
  664.                     ; ..above
  665.  
  666. do$6502$fun:
  667.     lhld    user$hl$temp
  668.     mov    a,l
  669.     jmp    ?fun65
  670. ;
  671. ;
  672. ;
  673. code$error:
  674.     lxi    h,date$hex
  675.     mvi    a,-1
  676.     ret
  677.  
  678.     page
  679. ;
  680. ;
  681. ;
  682.     CSEG
  683. ?rlccp:
  684.     lxi    h,ccp$buffer
  685.     lxi    b,0c80h
  686.  
  687. load$ccp:
  688.     sta    bank$0
  689.     mov    a,m
  690.     sta    bank$1
  691.     lxi    d,-ccp$buffer+100h
  692.     dad    d
  693.     mov    m,a
  694.     lxi    d,ccp$buffer-100h+1
  695.     dad    d
  696.     dcx    b
  697.     mov    a,b
  698.     ora    c
  699.     jrnz    load$ccp
  700.     ret
  701.  
  702.     page
  703. ;
  704. ;
  705. ;
  706.     CSEG
  707. ?ldccp:
  708.     xra    a
  709.     sta    ccp$fcb+15    ; zero extent
  710.     lxi    h,0
  711.     shld    fcb$nr        ; start at beginning of file
  712.     lxi    d,ccp$fcb
  713.     call    open        ; open file containing CCP
  714.     inr    a
  715.     jrz    no$CCP        ; error if no file...
  716.     lxi    d,0100h
  717.     call    setdma        ; start of TPAè    lxi    d,128
  718.     call    setmulti    ; allow up to 16K bytes
  719.     lxi    d,ccp$fcb
  720.     call    read
  721.  
  722.     lxi    h,0100h
  723.     lxi    b,0c80h
  724.     lda    force$map
  725.     push    psw
  726.  
  727. ;
  728. ;
  729. save$ccp:
  730.     sta    bank$1
  731.     mov    a,m
  732.     sta    bank$0
  733.     lxi    d,ccp$buffer-100h
  734.     dad    d
  735.     mov    m,a
  736.     lxi    d,-ccp$buffer+100h+1
  737.     dad    d
  738.     dcx    b
  739.     mov    a,b
  740.     ora    c
  741.     jrnz    save$ccp
  742.  
  743.     pop    psw
  744.     sta    force$map
  745.     ret
  746.  
  747.     page 
  748. ;
  749. ;    The following code does not work with the NEW MMU
  750. ;
  751. ;?ldccp:
  752. ;    xra    a
  753. ;    sta    ccp$fcb+15    ; zero extent
  754. ;    lxi    h,0
  755. ;    shld    fcb$nr        ; start at beginning of file
  756. ;    lxi    d,ccp$fcb
  757. ;    call    open        ; open file containing CCP
  758. ;    inr    a
  759. ;
  760. ;;    trace    jz below should be jrz
  761. ;    jz    no$CCP        ; error if no file...
  762. ;
  763. ;    lda    fcb$rc        ; get the record count
  764. ;    sta    ccp$count    ; save for later
  765. ;    lxi    d,0100h
  766. ;    call    setdma        ; start of TPAè;    lxi    d,128
  767. ;    call    setmulti    ; allow up to 16K bytes
  768. ;    lxi    d,ccp$fcb
  769. ;    call    read
  770. ;
  771. ;    lxi    d,1f0h        ; point to buffer
  772. ;                ; bank 1, page F0
  773. ;;    lxi    h,101h        ; point to CCP (in TPA)
  774. ;                ; bank 1, page 01
  775. ;    mov    h,d
  776. ;    mov    l,d
  777. ;    jr    save$ccp
  778. ;
  779. ;
  780. ;
  781. ;
  782. ;?rlccp:
  783. ;    lda    ccp$count    ;
  784. ;    sui    30        ; we can only save 30 records
  785. ;    jp    ?ldccp
  786. ;
  787. ;    lxi    h,1F0h        ; point to buffer
  788. ;                ; bank 1, page F0
  789. ;;    lxi    d,101h        ; point to TPA space
  790. ;                ; bank 1, page 01
  791. ;    mov    d,h
  792. ;    mov    e,h
  793. ;
  794. ;save$ccp:
  795. ;    mvi    b,15        ; number of pages in buffer
  796. ;ccp$move$loop:
  797. ;    push    h
  798. ;    push    d
  799. ;    push    b
  800. ;    call    do$move$0$to$1
  801. ;    pop    b
  802. ;    pop    d
  803. ;    pop    h
  804. ;    inx    h
  805. ;    inx    d
  806. ;    djnz    ccp$move$loop
  807. ;
  808. ;    ret
  809. ;
  810. ;
  811. ;do$move$0$to$1:
  812. ;    call    set$0$and$1
  813. ;    call    move$0$to$1
  814. ;    lxi    h,100h        ; bank 1 page 0
  815. ;;    lxi    d,101h        ; bank 1 page 1
  816. ;    mov    d,h
  817. ;    mov    e,h
  818. ;;
  819. ;;
  820. ;;
  821. ;set$0$and$1:
  822. ;    lda    force$map    ; get current map
  823. ;    sta    io        ; force to i/o in bank 0
  824. ;    lxi    b,page$0$l    ; point to 1st page register
  825. ;    outp    l        ; set page 0 low
  826. ;    inr    c
  827. ;    outp    h        ; set page 0 high
  828. ;    inr    c
  829. ;    outp    e        ; set page 1 low
  830. ;    inr    c
  831. ;    outp    d        ; set page 1 high
  832. ;    sta    force$map
  833. ;    ret
  834. ;
  835. ;;
  836. ;;
  837. ;;
  838. ;move$0$to$1: 
  839. ;    lda    force$map
  840. ;    sta    bank$1        ; force bank 1 memory
  841. ;    lxi    h,000h        ; source
  842. ;    lxi    d,100h        ; dest.
  843. ;;    lxi    b,100h
  844. ;    mov    b,d
  845. ;    mov    c,e        ; count
  846. ;    ldir
  847. ;    sta    force$map
  848. ;    ret
  849. ;
  850.     page
  851. ;
  852. ;
  853. ;
  854. no$CCP:                ; here if we couldn't find the file
  855.     call    prtmsg        ; report this...
  856.     db    cr,lf,'BIOS Err on A: No CCP.COM file',0
  857.     call    ?conin        ; get a response
  858.     jr    ?ldccp        ; and try again
  859.  
  860. ;
  861. ; CP/M BDOS Function Interfaces
  862. ;
  863.     CSEG
  864. open:
  865.     mvi    c,15        ; open file control block
  866.  
  867.     db    21h        ; lxi h,(mvi c,26)
  868. setdma:
  869.     mvi    c,26        ; set data transfer address
  870.  
  871.     db    21h        ; lxi h,(mvi c,44)    
  872. setmulti:
  873.     mvi    c,44        ; set record count
  874.  
  875.     db    21h        ; lxi h,(mvi c,20)
  876. read:
  877.     mvi    c,20        ; read records
  878.     jmp    bdos
  879.  
  880. ;               12345678901
  881. ccp$fcb        db    1,'CCP     COM',0,0,0
  882. fcb$rc        db    0
  883.         ds    16
  884. fcb$nr        db    0,0,0
  885.  
  886.  
  887.     page
  888. ;
  889. ;    CXIO.ASM and CXEM.ASM
  890. ;
  891. ;==========================================================
  892. ;        ROUITINE TO VECTOR TO HANDLER
  893. ;==========================================================
  894. ;    CP/M IO routines    b=device : c=output char : a=input char
  895. ;
  896.     CSEG
  897. ;
  898. ;
  899. ;
  900. ?cinit:                ; initialize usarts
  901.     mov    b,c
  902.     call    vector$io    ; jump with table adr on stack
  903. number$drivers:
  904.     dw    ?int$cia    ; keys
  905.     dw    ?int80        ; 80col
  906.     dw    ?int40        ; 40col
  907.     dw    ?pt$i$1101    ; prt1
  908.     dw    ?pt$i$1101    ; prt2
  909.     dw    ?int65        ; 6551
  910.    if    not use$6551
  911.     dw    init$RS232    ; software RS232
  912.    endif
  913.     dw    rret        ;
  914. max$devices    equ    (($-number$drivers)/2)-1
  915.  
  916. ;
  917. ;
  918. ;
  919. ?ci║                ╗ characte≥ input
  920.     call    vector$io    ; jump with table adr on stack
  921.     dw    key$board$in    ; keys
  922.     dw    rret        ; 80col
  923.     dw    rret        ; 40col
  924.     dw    rret        ; ptr1
  925.     dw    rret        ; prt2
  926.     dw    ?in65        ; 6551
  927.    if    not use$6551
  928.     dw    in$RS232    ; software RS232
  929.    endif
  930.     dw    null$input
  931.  
  932. ;
  933. ;
  934. ;
  935. ?cist:                ; character input status
  936.     call    vector$io    ; jump with table adr on stack
  937.     dw    key$board$stat    ; keys
  938.     dw    rret        ; 80col
  939.     dw    rret        ; 40col
  940.     dw    rret        ; prt1
  941.     dw    rret        ; prt2
  942.     dw    ?ins65        ; 6551
  943.    if    not use$6551
  944.     dw    in$st$RS232    ; software RS232
  945.    endif
  946.     dw    rret
  947.  
  948. ;
  949. ;
  950. ;
  951. ?co:                ; character output
  952.     call    vector$io    ; jump with table adr on stack
  953.     dw    rret        ; keys
  954.     dw    ?out80        ; 80col
  955.     dw    ?out40        ; 40col
  956.     dw    ?pt$o$1        ; prt1
  957.     dw    ?pt$o$2        ; prt2
  958.     dw    ?out65        ; 6551
  959.    if    not use$6551
  960.     dw    out$RS232    ; software RS232
  961.    endif
  962.     dw    rret
  963.  
  964. ;
  965. ;
  966. ;
  967. ?cost:                ; character output status
  968.     call    vector$io    ; jump with table adr on stack
  969.     dw    ret$true    ; keys
  970.     dw    ret$true    ; 80col
  971.     dw    ret$true    ; 40col
  972.     dw    ret$true    ; prt1    ?pt$s$1101
  973.     dw    ret$true    ; prt2
  974.     dw    ?outs65        ; 6551
  975.    if    not use$6551
  976.     dw    out$st$RS232    ; software RS232
  977.    endif
  978.     dw    ret$true
  979.  
  980.     page
  981. ;
  982. ;    This entry does not care about values of DE
  983. ;
  984. vector$io:
  985.     mvi    a,max$devices    ; check for device # to high
  986.     mov    e,b        ; get devive # in E
  987. ;
  988. ;
  989. ;    INPUT:
  990. ;        Vector # in E, Max device in A
  991. ;        passes value in DE$TEMP in DE
  992. ;        HL has routine's address in it on entering routine
  993. ;
  994. ;    OUTPUT:
  995. ;        ALL registers of returning routine are passed
  996. ;
  997. vector:
  998.     pop    h        ; get address vector list
  999.     mvi    d,0        ; zero out the MSB
  1000.     cmp    e        ; is it too high?
  1001.     jrnc    exist        ; no, go get the handler address
  1002.  
  1003.     mov    e,a        ; yes, set to max$dev$handler(last one) 
  1004. exist:
  1005.     dad    d        ; 
  1006.     dad    d        ; point into table
  1007.  
  1008.      mov    a,m
  1009.     inx    h
  1010.     mov    h,m
  1011.     mov    l,a        ; get routine adr in HL
  1012.  
  1013.     if    banked
  1014.     shld    hl$temp        ; save exec adr
  1015.     lxi    h,0
  1016.     dad    sp
  1017.     lxi    sp,bios$stack
  1018.     push    h        ; save old stack
  1019.  
  1020.     lhld    de$temp
  1021.     xchg
  1022.     lhld    hl$temp        ; recover exec adr
  1023.  
  1024.     lda    force$map    ; get current bank
  1025.     push    psw        ; save on stack
  1026.     sta    bank$0        ; set bank 0 as current
  1027.  
  1028.     call    ipchl
  1029.  
  1030.     sta    a$temp        ; save value to return
  1031.     pop    psw
  1032.     sta    force$map    ; set old bank back
  1033.     lda    a$temp        ; recover value to return
  1034.  
  1035.     shld    hl$temp
  1036.     pop    h        ; recover old stack
  1037.     sphl            ; set new stack
  1038.     lhld    hl$temp
  1039.     ret
  1040.  
  1041. ipchl:
  1042.     pchl            ; jmp to handler
  1043.  
  1044.     ds    30h
  1045. bios$stack:
  1046.  
  1047.     else
  1048.     lda    a$temp
  1049.     xchg
  1050.     lhld    de$temp
  1051.     xchg
  1052.     pchl
  1053.     endif
  1054.  
  1055.     page
  1056. ;==========================================================
  1057. ;        CHARACTER INPUT ROUTINES
  1058. ;==========================================================
  1059.  
  1060.     DSEG
  1061. ;
  1062. ;
  1063. ;
  1064. key$board$in:
  1065.     call    key$board$stat    ; test if key is available
  1066.     jrz    key$board$in    
  1067.  
  1068.     lda    key$buf
  1069.     push    psw        ; save on stack
  1070.     xra    a        ; clear key 
  1071.     sta    key$buf
  1072. ;
  1073. ;**    the tracking of the display should be able to be turned off
  1074. ;**    this could be done with one of the keyboard's Fx codes
  1075. ;
  1076.     lda    stat$enable
  1077.     bit    6,a
  1078.     jrnz    no$update
  1079.     lda    char$col$40
  1080.     mov    b,a
  1081.     lda    @off40
  1082.     cmp    b
  1083.     jrnc    do$update
  1084.     adi    39-1
  1085.     cmp    b
  1086.     jrnc    no$update
  1087. do$update:
  1088.     mvi    a,80h    
  1089.     sta    old$offset    ; store 80h to demand update
  1090. no$update:
  1091.     pop    psw        ; recover current key
  1092. rret:
  1093.     ret
  1094.  
  1095. ;
  1096. ;
  1097. ;
  1098. null$input:        ; return a ctl-Z for no device
  1099.     mvi    a,1Ah
  1100.     ret
  1101.  
  1102.  
  1103.     page
  1104.  
  1105. ;==========================================================
  1106. ;    CHARACTER DEVICE INPUT STATUS
  1107. ;==========================================================
  1108.  
  1109.     DSEG
  1110. ;
  1111. ;
  1112. ;
  1113. key$board$stat:
  1114.     lda    key$buf
  1115.     ora    a
  1116.     jrnz    ret$true
  1117.  
  1118.     call    ?get$key
  1119.     ora    a        ; =0 if none
  1120.     rz            ; return character not advailable
  1121.  
  1122.     sta    key$buf        ; was one, save in key buffer
  1123.  
  1124. ret$true:
  1125.     ori    0ffh        ; and return true
  1126.     ret
  1127.  
  1128.     page
  1129.  
  1130.     cseg
  1131. @ctbl
  1132.     db    'KEYS  '    ; device 0, internal keyboard
  1133.     db    mb$input
  1134.     db    baud$none
  1135.  
  1136.     db    '80COL '    ; device 1, 80 column display
  1137.     db    mb$output
  1138.     db    baud$none
  1139.  
  1140.     db    '40COL '    ; device 2, 40 column display
  1141.     db    mb$output
  1142.     db    baud$none
  1143.  
  1144.     db    'PRT1  '    ; device 3, serial bus printer (device 4)
  1145.     db    mb$output
  1146.     db    baud$none
  1147.  
  1148.     db    'PRT2  '    ; device 4, serial bus printer (device 5)
  1149.     db    mb$output
  1150.     db    baud$none
  1151.  
  1152.     db    '6551  '    ; device 5, EXT CRT
  1153.     db    mb$in$out+mb$serial+mb$softbaud+mb$xonxoff
  1154. ?intbd:
  1155.     db    baud$1200
  1156.    if    not use$6551
  1157.     db    'RS232 '    ; device 6, software RS232 device
  1158.     db    mb$in$out+mb$serial+mb$xonxoff+mb$softbaud
  1159. RS232$baud:
  1160.     db    baud$300
  1161.    endif
  1162.     db    0        ; mark end of table
  1163.  
  1164.     page
  1165. ;
  1166. ;    TIME.ASM
  1167. ;
  1168.     cseg
  1169. ;
  1170. ;    HL and DE must be presevered
  1171. ;
  1172. ?time:
  1173.     inr    c
  1174.     lxi    b,cia$hours
  1175.     jrz    set$time
  1176. ;
  1177. ;    update SCB time  (READ THE TIME)
  1178. ;
  1179.     inp    a            ; read HR (sets sign flag)
  1180.     jp    is$am            ; jmp if AM (positive)
  1181.     ani    7fh
  1182.     adi    12h            ; noon=24(PM), midnight=12(AM)
  1183.     daa
  1184.     cpi    24h            ; check for noon (12+12 PM)
  1185.     jrnz    set$hr
  1186.     mvi    a,12h
  1187.     jr    set$hr
  1188.  
  1189. is$am:
  1190.     cpi    12h            ; check for midnight (AM)
  1191.     jrnz    set$hr
  1192.     xra    a            ; becomes 00:00
  1193. set$hr:
  1194.     sta    @hour
  1195.     mov    b,a
  1196.     lda    old$hr
  1197.     mov    c,a
  1198.     mov    a,b
  1199.     sta    old$hr
  1200.     cmp    c            ; if @hour<old$hr
  1201.     jrnc    same$day
  1202.  
  1203.     push    h
  1204.     lhld    @date
  1205.     inx    h
  1206.     shld    @date
  1207.     pop    h
  1208.  
  1209. same$day:
  1210.     lxi    b,cia$hours-1
  1211.     inp    a            ; read MIN
  1212.     sta    @min
  1213.  
  1214.     dcr    c
  1215.     inp    a            ; read SEC
  1216.     sta    @sec
  1217.  
  1218.     dcr    c
  1219.     inp    a            ; read 1/10 of SEC (a must to free
  1220.     ret                ; the holding register)
  1221.  
  1222. old$hr:
  1223.     ds    1
  1224.  
  1225.     page
  1226. ;
  1227. ;
  1228. ;
  1229. set$time
  1230.     lda    @hour
  1231.     sta    old$hr
  1232.     cpi    12h            ; test for noon
  1233.     jrz    set$as$is
  1234.     ana    a            ; test for 00:xx
  1235.     jrnz    not$zero$hundred
  1236.     mvi    a,80h+12h            ; set to midnight
  1237.     jr    set$as$is
  1238.  
  1239. not$zero$hundred:
  1240.      cpi    11h+1            ; test for 1 to 11 AM
  1241.     jrc    set$as$is
  1242.     sui    12h
  1243.     daa                ; decimal adjust
  1244. set$msb:
  1245.     ori    80h            ; set PM
  1246.  
  1247. set$as$is:
  1248.     outp    a
  1249.     dcr    c
  1250.     lda    @min
  1251.     outp    a
  1252.     dcr    c
  1253.     lda    @sec
  1254.     outp    a
  1255.     dcr    c
  1256.     xra    a
  1257.     outp    a
  1258.     ret
  1259.  
  1260.     page
  1261. ;
  1262. ; CXMOVE.ASM
  1263. ;
  1264.     public ?move,?xmove,?bank
  1265.  
  1266. ;
  1267. ;    Move a block of data from DE to HL
  1268. ;    count is in BC (within current bank)
  1269. ;
  1270. ;
  1271.     cseg            ; place code in common
  1272. ?move:
  1273.     xchg            ;*
  1274.     lda    source$bnk    ; =FFh if normal block move 
  1275.     inr    a        ; 
  1276.     jrnz    inter$bank$move
  1277.  
  1278.     LDIR            ;* do block move    
  1279.     xchg            ;*
  1280.     ret
  1281.  
  1282.  
  1283. ;
  1284. ;
  1285. ;
  1286. ?xmove:                ; can be in bank 0    
  1287.     mov    a,c
  1288.     sta    source$bnk
  1289.     mov    a,b
  1290.     sta    dest$bnk
  1291.     ret            ;*
  1292.  
  1293.     page
  1294. ;
  1295. ;
  1296. ;
  1297. inter$bank$move:
  1298.     shld    @buffer        ; save HL TEMP
  1299.     lxi    h,0
  1300.     dad    sp
  1301.     lxi    sp,bios$stack
  1302.     push    h        ; save old stack  ;**1
  1303.     lhld    @buffer
  1304.  
  1305. inter$bank$move$1:
  1306.     mov    a,b        ; get msb of count
  1307.     ora    a
  1308.     jrz    count$less$than$256
  1309.     push    b        ; save the count  ;**2
  1310.     push    d        ; save the dest   ;**3
  1311.     lxi    d,@buffer    ; make buffer the dest
  1312.     lxi    b,256        ; move 256 bytes
  1313.     lda    source$bnk
  1314.     call    ?bank
  1315.     ldir            ; move source to buffer
  1316.  
  1317.     pop    d        ; recover dest    ;**2
  1318.     push    h        ; save updated source ;**3
  1319.     lxi    h,@buffer    ; make the buffer the source
  1320.     lxi    b,256        ; move 256 bytes
  1321.     lda    dest$bnk
  1322.     call    ?bank
  1323.     ldir            ; move buffer to dest
  1324.  
  1325.     pop    h        ; recover updated source ;**2
  1326.     pop    b        ; recover count          ;**1
  1327.     dcr    b        ; subtract 256 from count
  1328.     jr    inter$bank$move$1
  1329.  
  1330.     page
  1331. ;
  1332. ;
  1333. ;
  1334. count$less$than$256:
  1335.     ora    c        ; BC=0  [A (0) or'ed with C]
  1336.      jrz    exit$move
  1337.  
  1338.     push    d        ; save count for 2nd half  ;**2
  1339.     push    b        ; save dest adr            ;**3
  1340.     lxi    d,@buffer
  1341.     lda    source$bnk
  1342.     call    ?bank
  1343.     ldir            ; move source to buffer
  1344.  
  1345.     pop    b        ; recover count          ;**2
  1346.     pop    d        ; recover dest          ;**1
  1347.     push    h        ; save updated dest      ;**2
  1348.     lxi    h,@buffer
  1349.     lda    dest$bnk
  1350.     call    ?bank
  1351.     ldir            ; move buffer to dest
  1352.     pop    h                        ;**1
  1353. ;
  1354. ;
  1355. ;
  1356. exit$move:
  1357.     xchg
  1358.     mvi    a,-1
  1359.     sta    source$bnk    ; set MOVE back to normal
  1360.     lda    @cbnk
  1361.  
  1362.     shld    @buffer
  1363.     pop    h        ; recover old stack    ;**0
  1364.     sphl
  1365.     lhld    @buffer
  1366.  
  1367. ; call    ?bank        ; set current bank
  1368. ; ret
  1369.  
  1370.     page
  1371. ;
  1372. ;    switch bank to bank number in A
  1373. ;
  1374.     cseg            ; (must be in common)
  1375. ?bank:                
  1376.    if    banked
  1377.     ora    a        ; bank 0 ?
  1378.     jrnz    not$bank$0    ; go check for bank 1
  1379.  
  1380.     sta    bank$0        ; set bank 0
  1381.     ret
  1382.  
  1383. ;
  1384. ;
  1385. not$bank$0:
  1386.     dcr    a        ; bank 1 ?
  1387.     rnz            ; if not a valid bank just return
  1388.     sta    bank$1        ; set bank 1
  1389.    endif
  1390.     ret
  1391.  
  1392.     end
  1393.